home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 699 / sizer / sizer.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  9KB  |  281 lines

  1. /* Sizer.c
  2.  
  3.    by Fabbian G. Dufoe, III
  4.       350 Ling-A-Mor Terrace South
  5.       St. Petersburg, Florida  33705
  6.       813-823-2350
  7.  
  8.       GENIE: F.DUFOE3
  9.  
  10.    This software is in the public domain.  You may use it any way you wish.
  11.  
  12.    Sizer reports the number of bytes and blocks in a disk, file, or directory
  13.    and all included subdirectories.  The user selects the Sizer icon and uses
  14.    extended selection to indicate the other files and directories he wants
  15.    sized.  Sizer will open a workbench window with the number of blocks and
  16.    the number of bytes.  To terminate the program the user clicks on the
  17.    window's close gadget.
  18.  
  19.    Revison summary:
  20.    15 October 1991: Initial release.
  21.  
  22.    18 May 1992:
  23.       Fixed NULL pointer bug in GetSize() function.  Function was passing a
  24.       NULL pointer when it should have been passing a pointer to a NULL
  25.       string.
  26.  
  27.    13 June 1992:
  28.       Added code for reporting blocks for old file system (OFS) and fast
  29.       file system (FFS) disks.
  30.       Made CountBlocks() and GetSize() static and moved their prototypes
  31.       into this file.
  32.       Added code to update display for directory sizes as well as files.
  33. */
  34.  
  35. #include <workbench/startup.h>
  36. #include <string.h>
  37. #include "Sizer.h"
  38.  
  39. /* Prototypes for functions defined in Sizer.c */
  40.  
  41. #ifndef __NOPROTO
  42. #ifndef __PROTO
  43. #define __PROTO(a) a
  44. #endif
  45. #else
  46. #ifndef __PROTO
  47. #define __PROTO(a) ()
  48. #endif
  49. #endif
  50.  
  51. static long CountBlocks __PROTO((int blocksize,
  52.                                  LONG bytes));
  53. static void GetSize __PROTO((BPTR lock,
  54.                              char *name,
  55.                              struct record *Record));
  56.  
  57. void
  58. main(int argc,
  59.      char **argv)
  60. {
  61.    struct WBStartup *argmsg;
  62.    int i;
  63.    struct FileInfoBlock IconBlock;  /* Information about ".info" file */
  64.    BPTR ParentLock;
  65.    struct record Record =
  66.    {
  67.       NORM,    /* code      */
  68.       0,       /* bytes     */
  69.       0,       /* OFSblocks */                                                /* 13 June 1992 */
  70.       0,       /* FFSblocks */                                                /* 13 June 1992 */
  71.       0,       /* files     */
  72.       0        /* dirs      */
  73.    };
  74.    struct WBArg *wb_arg;
  75.  
  76.    if (argc == 0) /* Started from Workbench */
  77.    {
  78.       /* Since the program was started from the Workbench argv contains a
  79.          pointer to the Workbench startup message.  We'll save that pointer
  80.          in argmsg.  The Workbench startup message contains a pointer to an
  81.          array of arguments.  That pointer is in sm_ArgList.  Each argument
  82.          has a lock and a name.  The first argument is the program itself.
  83.          The number of arguments is stored in sm_NumArgs.
  84.       */
  85.       argmsg = (struct WBStartup *)argv;
  86.       wb_arg = argmsg->sm_ArgList;
  87.  
  88.       /* We'll try to open the input/output window.  We'll continue only if
  89.          we're successful.
  90.       */
  91.       SizerIO(&Record);
  92.       if (Record.code == NORM)
  93.       {
  94.          for (i = 1; i < argmsg->sm_NumArgs; i++)
  95.          {
  96.             /* We want to include the size of the icon file in our
  97.                calculations.  If the user selected a directory object we'll
  98.                have to Examine() it to find out its name, then switch to its
  99.                parent directory, append ".info" to the file name, and
  100.                Examine() the icon file to get its size.
  101.             */
  102.             if (*(wb_arg + i)->wa_Name == NULL)  /* Directory object */
  103.             {
  104.                if (Examine((wb_arg + i)->wa_Lock, &IconBlock) == 0)
  105.                {
  106.                   Record.code = FAIL;
  107.                   SizerIO(&Record);
  108.                   break;
  109.                }
  110.                else
  111.                {
  112.                   if (0 != (ParentLock = ParentDir((wb_arg + i)->wa_Lock)))
  113.                   {
  114.                      (void)strcat(IconBlock.fib_FileName, ".info");
  115.                      GetSize(ParentLock, IconBlock.fib_FileName, &Record);
  116.                      UnLock(ParentLock);
  117.                   }
  118.                }
  119.             }
  120.             else
  121.             {
  122.                strcpy(IconBlock.fib_FileName, (wb_arg + i)->wa_Name);
  123.                (void)strcat(IconBlock.fib_FileName, ".info");
  124.                GetSize((wb_arg + i)->wa_Lock,
  125.                        IconBlock.fib_FileName,
  126.                        &Record);
  127.             }
  128.             GetSize((wb_arg + i)->wa_Lock,
  129.                     (wb_arg + i)->wa_Name,
  130.                     &Record);
  131.          }
  132.          if (Record.code == NORM)
  133.          {
  134.             Record.code = DONE;
  135.             SizerIO(&Record);
  136.          }
  137.          Record.code = CLOSEIO;
  138.          SizerIO(&Record);
  139.       }
  140.    }
  141. }
  142.  
  143.  
  144. static long                                                                   /* 13 June 1992 */
  145. CountBlocks(int blocksize,
  146.             LONG bytes)
  147. /* FUNCTION
  148.       This function calculates the number of disk blocks needed by a file
  149.       based on the number of bytes in the file and the number of bytes in a
  150.       block.  The number of blocks is the sum of the File Header Block, the
  151.       data blocks, and any File List Blocks.  Data blocks are calculated by
  152.       dividing the number of bytes by the block size and adding another data
  153.       block for bytes left over (if there is a remainder).  Every file has
  154.       one File Header Block, which can accommodate up to 72 data blocks.  If
  155.       there are more data blocks, a File List Block is required for the file
  156.       extension.  The File List Block can accommodate 72 data blocks.  There
  157.       may be as many File List Blocks as needed for the data blocks.  If
  158.       there are no bytes in the file it is either an empty file or a
  159.       directory.  Either one requires a single block.
  160.  
  161.    INPUTS
  162.       blocksize   The number of bytes in a block
  163.       bytes       The number of bytes in the file
  164.  
  165.    RESULTS
  166.       The function returns the number of blocks the file will require.  The
  167.       minimum value is 1.
  168. */
  169. {
  170.    long blocks;
  171.  
  172.    if (bytes > 0)
  173.    {
  174.       blocks = bytes / blocksize;
  175.       if ((bytes % blocksize) != 0)
  176.       {
  177.          blocks++;
  178.       }
  179.       if ((blocks % 72) == 0)
  180.       {
  181.          blocks += blocks / 72;
  182.          blocks--;
  183.       }
  184.       else
  185.       {
  186.          blocks += blocks / 72;
  187.       }
  188.       blocks += 1;
  189.    }
  190.    else
  191.    {
  192.       blocks = 1;
  193.    }
  194.    return(blocks);
  195. }
  196.  
  197.  
  198. static void                                                                   /* 13 June 1992 */
  199. GetSize(BPTR lock,
  200.         char *name,
  201.         struct record *Record)
  202. {
  203.    struct FileInfoBlock infoBlock;
  204.    BPTR objlock;
  205.    BPTR olddir;
  206.  
  207.    if (Record->code == FAIL)
  208.       return;
  209.  
  210.    olddir = CurrentDir(lock);
  211.    if (*name == NULL)    /* Directory object */
  212.    {
  213.       /* Examine everything in the directory and accumulate the sizes. */
  214.       if (Examine(lock, &infoBlock) == 0)
  215.       {
  216.          Record->code = FAIL;
  217.          SizerIO(Record);
  218.       }
  219.       else
  220.       {
  221.          Record->bytes += infoBlock.fib_Size;
  222.          Record->OFSblocks += CountBlocks(488, 0);                            /* 13 June 1992 */
  223.          Record->FFSblocks += CountBlocks(512, 0);                            /* 13 June 1992 */
  224.          Record->dirs++;                                                      /* 13 June 1992 */
  225.          while ((ExNext(lock, &infoBlock) != 0) && (Record->code == NORM))
  226.          {
  227.             if (infoBlock.fib_DirEntryType > 0) /* Directory */
  228.             {
  229.                if ((objlock = Lock(infoBlock.fib_FileName, ACCESS_READ))
  230.                    == 0)
  231.                {
  232.                   Record->code = FAIL;
  233.                   SizerIO(Record);
  234.                }
  235.                else
  236.                {
  237.                   GetSize(objlock, "\0", Record);                             /* 18 May 1992 */
  238.                   UnLock(objlock);
  239.                   SizerIO(Record);                                            /* 13 June 1992 */
  240.                }
  241.             }
  242.             else
  243.             {
  244.                Record->bytes += infoBlock.fib_Size;
  245.                Record->OFSblocks += CountBlocks(488, infoBlock.fib_Size);     /* 13 June 1992 */
  246.                Record->FFSblocks += CountBlocks(512, infoBlock.fib_Size);     /* 13 June 1992 */
  247.                Record->files++;
  248.                SizerIO(Record);
  249.             }
  250.          }
  251.       }
  252.    }
  253.    else  /* Plain file */
  254.    {
  255.       if ((objlock = Lock(name, ACCESS_READ)) == 0)
  256.       {
  257.          Record->code = FAIL;
  258.          SizerIO(Record);
  259.       }
  260.       else
  261.       {
  262.          if (Examine(objlock, &infoBlock) == 0)
  263.          {
  264.             Record->code = FAIL;
  265.             SizerIO(Record);
  266.          }
  267.          else
  268.          {
  269.             Record->bytes += infoBlock.fib_Size;
  270.             Record->OFSblocks += CountBlocks(488, infoBlock.fib_Size);        /* 13 June 1992 */
  271.             Record->FFSblocks += CountBlocks(512, infoBlock.fib_Size);        /* 13 June 1992 */
  272.             Record->files++;
  273.             SizerIO(Record);
  274.          }
  275.          UnLock(objlock);
  276.       }
  277.    }
  278.    (void)CurrentDir(olddir);
  279.    return;
  280. }
  281.